package com.terrynoya.fight.stateMachine
{
	import com.terrynoya.common.util.HashMap;
	import com.terrynoya.coreLib.MHashMap;
	import com.terrynoya.fight.char.Character;
	import com.terrynoya.fight.char.Entity;
	import com.terrynoya.fight.evaluation.Expression;
	import com.terrynoya.fight.evaluation.Node;
	import com.terrynoya.fight.io.KeyValuePair;
	import com.terrynoya.fight.io.TextSection;
	import com.terrynoya.fight.stateMachine.triggers.ITrigger;
	import com.terrynoya.geom.MVector2D;

	public class StateController
	{
		private var _name:String;
		
		private var _triggers:TriggerMap;
		
		private var _ignoreHitPause:Boolean;
		
		private var _expressions:MHashMap;
		
		private var _attrConvertMap:MHashMap;
		
		private var _attributeMap:MHashMap;
		
		private var _stateSystem:StateSystem;
		
		private var _persistence:int;
		
		public function StateController(name:String)
		{
			this._name = name;
			this._triggers = new TriggerMap();
			this._attributeMap = new MHashMap();
			this._attrConvertMap = new MHashMap();
			this._expressions = new MHashMap();
			this.initAttrConvertMap();
		}
		
		public function transAttrToVec(attrName:String,character:Character):MVector2D
		{
			var vec:MVector2D = new MVector2D(); 
			var input:String = this.getAttribute(attrName);
			var arr:Array = this.stateSystem.buildFullExpression(input);
			if(arr.length >= 1)
			{
				var nodeX:Node = arr[0];
				vec.x = nodeX.excute(character);
			}
			if(arr.length == 2)
			{
				var nodeY:Node = arr[1];
				vec.y = nodeY.excute(character);
			}
			return vec;
		}
		
		/**
		 * 如果为0，状态只会被触发一次
		 * 如果为1，每个tick满足条件都会被触发
		 * 如果>1，每个tick将会-1
		 * @return 
		 * 
		 */		
		public function get persistence():int
		{
			return _persistence;
		}

		public function set persistence(value:int):void
		{
			_persistence = value;
		}

		public function get stateSystem():StateSystem
		{
			return _stateSystem;
		}

		public function set stateSystem(value:StateSystem):void
		{
			_stateSystem = value;
		}

		public function build():void
		{
			this.persistence = this.getAttributeAsInt("persistent",1);
		}
		
		public function addAttrbute(key:String,value:String):void
		{
			this._attributeMap.put(key,value);
		}
		
		public function getAttributeAsNumber(key:String,nullVal:Number = 0):Number
		{
			if(!this._attributeMap.containsKey(key))
			{
				return nullVal;
			}
			return Number(this.getAttribute(key));
		}
		
		public function getAttributeAsInt(key:String,nullVal:int = 0):int
		{
			if(!this._attributeMap.containsKey(key))
			{
				return nullVal;
			}
			return int(this.getAttribute(key));
		}
		
		public function getAttributeAsBoolean(key:String,nullVal:Boolean = false):Boolean
		{
			if(!this._attributeMap.containsKey(key))
			{
				return nullVal;
			}
			var intVal:int = int(this.getAttribute(key));
			var isNotZero:Boolean = intVal != 0;
			return isNotZero == true;
		}
		
		public function getAttribute(key:String):String
		{
			if(!this._attributeMap.containsKey(key))
			{
				return "";
			}
			return this._attributeMap.getValue(key);
		}
		
		public function hasAttribute(key:String):Boolean
		{
			return this._attributeMap.containsKey(key);
		}
		
		public function get attributeMap():MHashMap
		{
			return _attributeMap;
		}

		public function set attributeMap(value:MHashMap):void
		{
			_attributeMap = value;
		}

		public function get attrConvertMap():MHashMap
		{
			return _attrConvertMap;
		}

		public function set attrConvertMap(value:MHashMap):void
		{
			_attrConvertMap = value;
		}

		protected function initAttrConvertMap():void
		{
			
		}
		
		public function getAttrConvertMap():MHashMap
		{
			return this._attrConvertMap;
		}
		
		public function getExpression(key:String):Expression
		{
			return this._expressions.getValue(key);
		}
		
		public function excuteExpression(key:String,data:Object):*
		{
			if(!this._expressions.containsKey(key))
			{
				return null;
			}
			return this.getExpression(key).excute(data);
		}
		
		public function hasExpression(key:String):Boolean
		{
			return this._expressions.containsKey(key);
		}
		
		public function get expressions():MHashMap
		{
			return _expressions;
		}

		public function set expressions(value:MHashMap):void
		{
			_expressions = value;
		}

		public function get name():String
		{
			return _name;
		}
		
		public function addTrigger(id:int,value:ITrigger):void
		{
			this._triggers.add(id,value);
		}
		
		public function get ignoreHitPause():Boolean
		{
			return _ignoreHitPause;
		}

		public function set ignoreHitPause(value:Boolean):void
		{
			_ignoreHitPause = value;
		}

		public function get triggers():TriggerMap
		{
			return _triggers;
		}

		public function set triggers(value:TriggerMap):void
		{
			_triggers = value;
		}

		public function run(character:Character):void
		{
			
		}
	}
}